﻿using Microsoft.Extensions.Localization;
using System.Collections.Generic;
using Volo.Abp.Caching;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;

namespace Volo.Abp.LanguageManagement
{
	public class DynamicResourceLocalizer : IDynamicResourceLocalizer, ISingletonDependency
	{
		protected ILanguageTextRepository LanguageTextRepository { get; }

		protected IDistributedCache<LanguageTextCacheItem> Cache { get; }

		public DynamicResourceLocalizer(ILanguageTextRepository languageTextRepository, IDistributedCache<LanguageTextCacheItem> cache)
		{
			this.LanguageTextRepository = languageTextRepository;
			this.Cache = cache;
		}

		public virtual LocalizedString GetOrNull(LocalizationResource resource, string cultureName, string name)
		{
			string orDefault = this.GetCacheItem(resource, cultureName).Dictionary.GetOrDefault<string, string>(name);
			if (orDefault == null)
			{
				return null;
			}
			return new LocalizedString(name, orDefault);
		}

		public virtual void Fill(LocalizationResource resource, string cultureName, Dictionary<string, LocalizedString> dictionary)
		{
			foreach (KeyValuePair<string, string> keyValuePair in this.GetCacheItem(resource, cultureName).Dictionary)
			{
				dictionary[keyValuePair.Key] = new LocalizedString(keyValuePair.Key, keyValuePair.Value);
			}
		}

		protected virtual LanguageTextCacheItem GetCacheItem(LocalizationResource resource, string cultureName)
		{
			var cacheItem = new CacheItem();
			cacheItem.localizer = this;
			cacheItem.resource = resource;
			cacheItem.key = cultureName;
			return this.Cache.GetOrAdd(LanguageTextCacheItem.CalculateCacheKey(cacheItem.resource.ResourceName, cacheItem.key), cacheItem.Create);
		}

		protected virtual LanguageTextCacheItem CreateCacheItem(LocalizationResource resource, string cultureName)
		{
			LanguageTextCacheItem languageTextCacheItem = new LanguageTextCacheItem();
			foreach (LanguageText languageText in this.LanguageTextRepository.GetList(resource.ResourceName, cultureName))
			{
				languageTextCacheItem.Dictionary[languageText.Name] = languageText.Value;
			}
			return languageTextCacheItem;
		}

		private sealed class CacheItem
		{

			internal LanguageTextCacheItem Create()
			{
				return this.localizer.CreateCacheItem(this.resource, this.key);
			}

			public DynamicResourceLocalizer localizer;

			public LocalizationResource resource;

			public string key;
		}
	}
}
